﻿using System;
using System.Linq;
using Coolite.Ext.Web;
using Microsoft.Practices.ServiceLocation;
using Pap.Core.Utilities;
using Pap.Data;
using Pap.Services.Parent;
using Pap.Web.Modules.Loan.ViewModel;
using Pap.Web.Utils;
using Utils.UIPermission;
using Pap.Core.Logging;

namespace Pap.Web.Modules.Loan.Views
{
    /// <summary>
    /// 
    /// </summary>
    public partial class CreateLoan : BasePage<CreateLoanViewModel>, IPermittedPage
    {

        #region [ ViewState]

        /// <summary>
        /// Gets or sets the birth date.
        /// </summary>
        /// <value>
        /// The birth date.
        /// </value>
        DateTime BirthDate
        {
            get
            {
                if (ViewState["BirthDate"] == null)
                {
                    return DateTime.Parse(txtBirthDate.Text);
                }
                return (DateTime)ViewState["BirthDate"];
            }
            set
            {
                ViewState["BirthDate"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the current stage id.
        /// </summary>
        /// <value>
        /// The current stage id.
        /// </value>
        Guid CurrentStageId
        {
            get
            {
                return (Guid)this.ViewState["CurrentStage"];
            }
            set
            {
                this.ViewState["CurrentStage"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the age limit.
        /// </summary>
        /// <value>
        /// The age limit.
        /// </value>
        int AgeLimit
        {
            get
            {
                return (int)ViewState["AgeLimit"];
            }
            set
            {
                ViewState["AgeLimit"] = value;
            }
        }

        #endregion

        #region [ QueryString ]

        /// <summary>
        /// Gets the customerID from the QueryString.
        /// </summary>
        /// <value>
        /// The customer ID.
        /// </value>
        public string CustomerID
        {
            get
            {
                return Request.QueryString["CustomerID"];
            }
        }

        /// <summary>
        /// Gets the loan ID from the QueryString.
        /// </summary>
        /// <value>
        /// The loan ID.
        /// </value>
        public string LoanID
        {
            get
            {
                return Request.QueryString["LoanID"];
            }
        }

        #endregion

        #region [ Functions ]

        /// <summary>
        /// Fills the stores.
        /// </summary>
        private void FillStores()
        {
            var governoratesLst = this.ViewModel.GetAllGovernates();
            var centersLst = this.ViewModel.GetAllCenters();

            storeGovernorates.DataSource = governoratesLst;
            storeGovernorates.DataBind();
            storeBirthLocations.DataSource = centersLst;
            storeBirthLocations.DataBind();

            storeCreationGovernorates.DataSource = governoratesLst;
            storeCreationGovernorates.DataBind();
            storeCreationCenters.DataSource = centersLst;
            storeCreationCenters.DataBind();
            storeCreationLocations.DataSource = this.ViewModel.GetAllLocations();
            storeCreationLocations.DataBind();

            storeEducationalLevels.DataSource = this.ViewModel.GetAllEducationalLevels();
            storeEducationalLevels.DataBind();
            storeSocialStatuses.DataSource = this.ViewModel.GetAllSocialStatuses();
            storeSocialStatuses.DataBind();
            storeLegalForms.DataSource = this.ViewModel.GetAllLegalForms();
            storeLegalForms.DataBind();
            storeLoanPlaces.DataSource = this.ViewModel.GetAllLoanPlaces();
            storeLoanPlaces.DataBind();
            storeLoanPaymentMethods.DataSource = this.ViewModel.GetAllLoanPaymentMethods();
            storeLoanPaymentMethods.DataBind();
            rdlLoanType.DataSource = this.ViewModel.GetAllLoanTypes();
            rdlLoanType.DataBind();
            storeMilitaryStatus.DataSource = this.ViewModel.GetAllMilitaryStatus();
            storeMilitaryStatus.DataBind();
        }

        /// <summary>
        /// Fills the loan data and customer data too.
        /// </summary>
        /// <param name="loanId">The loan ID.</param>
        protected void FillLoanData(Guid loanId)
        {
            ICustomerLoan loan = this.ViewModel.GetLoanById(loanId);
            txtLoanName.Text = loan.LoanName;
            txtLoanAmount.Text = loan.LoanAmount.ToString();
            txtloanPaymentPeriod.Text = loan.LoanPaymentPeriod.ToString();
            txtLoanProjectAddress.Text = loan.LoanAddress;
            txtFamilyCurrentDebts.Text = loan.FamilyCurrentDebts;
            txtReciptNumber.Text = loan.Receipt.ReceiptNumber.ToString();
            txtRelationToCommitteeMember.Text = loan.RelationWithManagers;
            cmbLoanPaymentMethods.SelectedItem.Value = loan.LoanPaymentMethodID.ToString();
            cmbLoanPlaces.SelectedItem.Value = loan.LoanPlaceTypeID.ToString();
            FillCustomerData(loan.CustomerObj);
            rdlLoanType.SelectedValue = loan.LoanTypeID.ToString();
            cmbLegalForm.SelectedItem.Value = loan.LegalFormID.ToString();

            txtReciptNumber.ReadOnly = true;

            IParentService parentService = ServiceLocator.Current.GetInstance<IParentService>();
            Guid projectId = loan.ProjectStage.ProjectID;
            SetCurrentProject(loan.ProjectStage);
        }

        /// <summary>
        /// Fills the customer data.
        /// </summary>
        /// <param name="oldCustomer">The old customer.</param>
        private void FillCustomerData(ICustomer oldCustomer)
        {
            txtCustomer.Text = oldCustomer.CustomerName;
            txtSSID.Text = oldCustomer.SSN.Trim();
            BirthDate = oldCustomer.Birthdate;
            txtBirthDate.Text = oldCustomer.Birthdate.ToString("dd-MM-yyyy");
            txtCurrentJob.Text = oldCustomer.CurrentJob;
            cmbBirthLocations.SelectedItem.Value = oldCustomer.BirthLocationID.ToString();

            txtSSIDYear.Text = oldCustomer.SSNCreationDate.Year.ToString();
            cmbSSIDMonth.SelectedItem.Value = oldCustomer.SSNCreationDate.Month.ToString();
            cmbMilitaryStatus.SelectedItem.Value = oldCustomer.MilitaryStatusID.ToString();
            if (oldCustomer.MilitaryPostpondingDate != null)
            {
                dateMilitary.Value = oldCustomer.MilitaryPostpondingDate;
                dateMilitary.Show();
            }
            else
            {
                dateMilitary.AllowBlank = true;
            }
            cmbCreationLocation.SelectedItem.Value = oldCustomer.IssuePlaceObj.IssuePlaceID.ToString();
            cmbEducationalLevel.SelectedItem.Value = oldCustomer.EducationalLevel.ID.ToString();
            txtAddress.Text = oldCustomer.Address;
            cmbSocialStatus.SelectedItem.Value = oldCustomer.SocialStatuse.ID.ToString();
            txtTele.Text = oldCustomer.Phones.Where(phone => phone.PhoneType == Convert.ToByte(PhoneType.Phone)).First().PhoneNumber.Trim();
            txtMobile.Text = oldCustomer.Phones.Where(mob => mob.PhoneType == Convert.ToByte(PhoneType.Mobile)).FirstOrDefault().PhoneNumber.Trim();

            if (oldCustomer.Gender == CustomerGender.Male)
            {
                radioMale.Checked = true;
                radioFemale.Checked = false;
            }
            else
            {
                radioFemale.Checked = true;
                radioMale.Checked = false;
            }

            IParentService parentService = ServiceLocator.Current.GetInstance<IParentService>();
            ICenter center = parentService.GetParentCenter(oldCustomer.SSNCreationLocationID);
            IGovernorate governorate = parentService.GetParentGovernorate(center.CenterID);

            foreach (var item in governorate.Centers)
            {
                cmbCreationCenters.Items.Add(new ListItem(item.CenterName, item.CenterID.ToString()));
            }
            foreach (var item in center.IssuePlaces)
            {
                cmbCreationLocation.Items.Add(new ListItem(item.IssuePlaceName, item.IssuePlaceID.ToString()));
            }

            cmbCreationGovernorates.SelectedItem.Value = governorate.GovernorateID.ToString();
            cmbCreationCenters.SelectedItem.Value = center.CenterID.ToString();
            cmbCreationLocation.SelectedItem.Value = oldCustomer.IssuePlaceObj.IssuePlaceID.ToString();

            governorate = parentService.GetParentGovernorate(oldCustomer.BirthLocationID);
            foreach (var item in governorate.Centers)
            {
                cmbBirthLocations.Items.Add(new ListItem(item.CenterName, item.CenterID.ToString()));
            }
            cmbGovernates.SelectedItem.Value = governorate.GovernorateID.ToString();
            cmbBirthLocations.SelectedItem.Value = oldCustomer.BirthLocationID.ToString();
        }

        /// <summary>
        /// Sets the current project.
        /// </summary>
        /// <param name="currentStage">The current stage.</param>
        private void SetCurrentProject(IProjectStage currentStage)
        {
            CurrentStageId = currentStage.ProjectStageID;
            AgeLimit = currentStage.AgeLimit;

            storeProjects.DataSource = this.ViewModel.GetAllProjects();
            storeProjects.DataBind();
            cmbProject.SelectedItem.Value = currentStage.ProjectID.ToString();
            cmbProject.Disabled = true;

            storeProjectStages.DataSource = this.ViewModel.GetAllProjectStages(currentStage.ProjectID);
            storeProjectStages.DataBind();
            cmbProjectStage.SelectedItem.Value = currentStage.ProjectStageID.ToString();
            cmbProjectStage.Disabled = true;

            txtLoanAmount.MinValue = currentStage.From;
            //txtLoanAmount.MaxValue = currentStage.To;
        }

        /// <summary>
        /// Sets the receipt mode.
        /// </summary>
        private void SetReceiptMode()
        {
            if (LoanID.IsNullOrEmpty())
            {
                if (this.ViewModel.GetReceipteMode())
                {
                    pnlReceipt.Hidden = true;
                    txtReciptNumber.AllowBlank = true;
                }
                else
                {
                    pnlReceipt.Hidden = false;
                    txtReciptNumber.ReadOnly = false;
                    txtReciptNumber.AllowBlank = false;
                }
            }
            else
            {
                pnlReceipt.Hidden = false;
                txtReciptNumber.ReadOnly = true;
            }
        }

        /// <summary>
        /// Clears the controls.
        /// </summary>
        protected void ClearControls()
        {
            txtAddress.Reset();
            txtBirthDate.Reset();
            txtCurrentJob.Reset();
            txtCustomer.Reset();
            txtFamilyCurrentDebts.Reset();
            txtLoanAmount.Reset();
            txtLoanName.Reset();
            txtloanPaymentPeriod.Reset();
            txtLoanProjectAddress.Reset();
            txtMobile.Reset();
            txtRelationToCommitteeMember.Reset();
            txtSSID.Reset();
            txtTele.Reset();

            cmbBirthLocations.Reset();
            cmbGovernates.Reset();

            cmbCreationCenters.Reset();
            cmbCreationLocation.Reset();
            cmbCreationGovernorates.Reset();

            cmbProjectStage.Reset();
            cmbProject.Reset();

            cmbSocialStatus.Reset();
            cmbEducationalLevel.Reset();
            cmbLegalForm.Reset();
            cmbLoanPaymentMethods.Reset();
            cmbLoanPlaces.Reset();

            ageLimit.Text = "300";
            dateMilitary.Reset();

            txtSSIDYear.Reset();
            cmbSSIDMonth.Reset();

        }

        /// <summary>
        /// Saves the customer loan.
        /// </summary>
        private void SaveCustomerLoan()
        {
            CustomerGender customerGender = GetSelectedGender();
            bool loanExist = GetLoanExist();
            DateTime? tempDate = GetMilitaryDate();

            this.ViewModel.setAgeExceedanceFlag(BirthDate, AgeLimit);
            if (this.ViewModel.IsNewSsid(txtSSID.Text.ToLower()) || !CustomerID.IsNullOrEmpty() || !LoanID.IsNullOrEmpty())
            {
                try
                {
                    ICustomerLoan loan = this.ViewModel.CreateCustomerAndLoan(txtCustomer.Text, BirthDate, customerGender,
                        txtSSID.Text, new DateTime(int.Parse(txtSSIDYear.Text), cmbSSIDMonth.SelectedItem.Value.ToInt32(), 1), cmbCreationLocation.SelectedItem.Value.ToGuid(), cmbBirthLocations.SelectedItem.Value.ToGuid(), cmbGovernates.SelectedItem.Value.ToGuid(), txtAddress.Text, txtTele.Text, txtMobile.Text,
                        txtRelationToCommitteeMember.Text, txtCurrentJob.Text, cmbMilitaryStatus.SelectedItem.Value.ToGuid(), tempDate, cmbSocialStatus.SelectedItem.Value.ToGuid(), cmbEducationalLevel.SelectedItem.Value.ToGuid(),
                        cmbProjectStage.SelectedItem.Value.ToGuid(), RegistryInfo.CommitteeID, txtLoanName.Text, txtLoanProjectAddress.Text, cmbLoanPlaces.SelectedItem.Value.ToGuid(), Convert.ToDouble(txtLoanAmount.Text), txtloanPaymentPeriod.Text.ToInt32(), txtFamilyCurrentDebts.Text,
                        cmbLegalForm.SelectedItem.Value.ToGuid(), rdlLoanType.SelectedValue.ToGuid(), txtRelationToCommitteeMember.Text, txtReciptNumber.Text, cmbLoanPaymentMethods.SelectedItem.Value.ToGuid(), loanExist, LoanID, CustomerID);

                    PostSave(loan);
                }
                catch (Exception exp)
                {
                    this.ViewModel.GetInstance<ILog>().RaiseError(exp);
                    Ext.Msg.Configure(new MessageBox.Config
                    {
                        Title = GetLocalResourceObject("MBError").ToString(),
                        Message = GetLocalResourceObject("MSGError").ToString(),
                        Icon = MessageBox.Icon.ERROR,
                        Buttons = MessageBox.Button.OK
                    }).Show();
                }
            }
            else
            {
                txtSSID.MarkInvalid(GetLocalResourceObject("NotNewUserError").ToString());
                txtBirthDate.Text = string.Empty;
            }
            //else
            //{
            //    txtBirthDate.MarkInvalid(GetLocalResourceObject("txtBirthDateResource1.VtypeText").ToString());
            //}
        }

        /// <summary>
        /// Posts the save.
        /// </summary>
        /// <param name="loan">The loan.</param>
        private void PostSave(ICustomerLoan loan)
        {
            if (LoanID.IsNullOrEmpty() && CustomerID.IsNullOrEmpty())
            {
                ShowRecipteWindow(loan.LoanNumber, loan.CustomerObj.CustomerName, loan.Receipt);
                this.ClearControls();
                this.SetReceiptMode();
            }
            else this.RedirectToPreviousPage();
        }

        /// <summary>
        /// Gets the military date.
        /// </summary>
        /// <returns></returns>
        private DateTime? GetMilitaryDate()
        {
            DateTime temp = Convert.ToDateTime(dateMilitary.Value);
            if (temp == DateTime.MinValue)
                return null;
            else
                return temp;
            /*
            if (dateMilitary.Hidden)
                return null;
            return Convert.ToDateTime(dateMilitary.Value);
            */
        }

        /// <summary>
        /// Gets the loan exist.
        /// </summary>
        /// <returns></returns>
        private bool GetLoanExist()
        {
            if (radioStill.Checked)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Gets the selected gender.
        /// </summary>
        /// <returns></returns>
        private CustomerGender GetSelectedGender()
        {
            CustomerGender customerGender = CustomerGender.Male;
            if (radioMale.Checked)
            {
                customerGender = CustomerGender.Male;
            }
            else
            {
                if (radioFemale.Checked)
                {
                    customerGender = CustomerGender.Female;
                }
            }
            return customerGender;
        }

        #endregion

        #region [ Events ]

        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Ext.IsAjaxRequest && !Page.IsPostBack)
            {
                dateMilitary.Hide();
                dateMilitary.MaxDate = DateTime.Now;
                bool hasOpenLoans;
                IProjectStage currentStage = this.ViewModel.GetNextStage(CustomerID, out hasOpenLoans);
                if (currentStage == null)
                {
                    InvalidCustomer(hasOpenLoans);
                }
                else
                {
                    FillStores();
                    if (rdlLoanType.Items.Count > 0)
                    {
                        rdlLoanType.SelectedIndex = 0;
                    }
                    if (!CustomerID.IsNullOrEmpty())
                    {
                        FillCustomerData(this.ViewModel.GetCustomerById(new Guid(CustomerID)));
                    }
                    if (!LoanID.IsNullOrEmpty())
                    {
                        FillLoanData(new Guid(LoanID));
                    }
                    else
                        SetCurrentProject(currentStage);
                    SetReceiptMode();
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void btnSave_Click(object sender, AjaxEventArgs e)
        {
            SaveCustomerLoan();
        }

        /// <summary>
        /// Invalids the customer.
        /// </summary>
        /// <param name="hasOpenLoans">if set to <c>true</c> [has open loans].</param>
        private void InvalidCustomer(bool hasOpenLoans)
        {
            if (hasOpenLoans)
            {
                Ext.Msg.Configure(new MessageBox.Config
                {
                    Buttons = MessageBox.Button.OK,
                    Title = GetLocalResourceObject("MBError").ToString(),
                    Message = GetLocalResourceObject("HasOpenLoans").ToString(),
                    Icon = MessageBox.Icon.ERROR
                }).Show();
                btnSave.Disabled = true;
            }
            else
            {
                Ext.Msg.Configure(new MessageBox.Config
                {
                    Buttons = MessageBox.Button.OK,
                    Title = GetLocalResourceObject("MBError").ToString(),
                    Message = GetLocalResourceObject("HasAll").ToString(),
                    Icon = MessageBox.Icon.ERROR
                }).Show();
                btnSave.Disabled = true;
            }
        }

        /// <summary>
        /// Handles the Changed event of the txtSSID control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void txtSSID_Changed(object sender, AjaxEventArgs e)
        {
            if (txtSSID.Text.Length == 14)
            {
                try
                {
                    int year = int.Parse("19" + txtSSID.Text.Substring(1, 2));
                    int month = int.Parse(txtSSID.Text.Substring(3, 2));
                    int day = int.Parse(txtSSID.Text.Substring(5, 2));
                    BirthDate = new DateTime(year, month, day);
                    txtBirthDate.Text = BirthDate.ToString("dd-MM-yyyy");
                    if (CustomerID.IsNullOrEmpty())
                    {
                        if (!this.ViewModel.IsNewSsid(txtSSID.Text.ToLower()))
                        {
                            txtSSID.MarkInvalid(GetLocalResourceObject("NotNewUserError").ToString());
                            //txtBirthDate.Text = string.Empty;
                        }
                        else
                        {
                            if (!this.ViewModel.ValidateGurantorWarning(txtSSID.Text))
                                panelGuarantorError.Show();
                            else
                                panelGuarantorError.Hide();
                        }
                    }

                }
                catch
                {
                    txtSSID.MarkInvalid();
                    txtBirthDate.Text = string.Empty;
                }


            }
        }

        #region [ Buttons ]

        /// <summary>
        /// Handles the Clicked event of the BtnBack control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnBack_Clicked(object sender, AjaxEventArgs e)
        {
            this.RedirectToPreviousPage();
        }

        #endregion

        #region [ ComboBoxes ]

        /// <summary>
        /// Handles the Select event of the CmbProjects.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void CmbProjects_Selected(object sender, AjaxEventArgs e)
        {
            if (!cmbProject.SelectedItem.Value.IsNullOrEmpty())
            {
                storeProjectStages.DataSource = this.ViewModel.GetAllProjectStages(cmbProject.SelectedItem.Value.ToGuid());
                storeProjectStages.DataBind();
            }
            else cmbProjectStage.Reset();
        }

        /// <summary>
        /// Handles the Select event of the CmbProjectStage.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void CmbProjectStage_Selected(object sender, AjaxEventArgs e)
        {
            IProjectStage projectStage = this.ViewModel.GetProjectStageById(cmbProjectStage.SelectedItem.Value.ToGuid());
            //txtLoanAmount.MaxValue = projectStage.To;
            txtLoanAmount.MinValue = projectStage.From;
            ageLimit.Text = projectStage.AgeLimit.ToString();
        }

        #endregion

        #region [ Receipte ]

        /// <summary>
        /// Shows the recipte window.
        /// </summary>
        /// <param name="loanNumber">The loan number.</param>
        /// <param name="customerName">Name of the customer.</param>
        /// <param name="recipte">The recipte.</param>
        protected void ShowRecipteWindow(int loanNumber, string customerName, IReceipt recipte)
        {
            wndGenerateRecipteNumber.LoadContent(string.Format("~/Loan.route/Receipt?CustomerName={0}&LoanNumber={1}&ReceipteNumber={2}&ReceiptDate={3}&ReceiptAmount={4}",
                                                                  customerName, loanNumber, recipte.ReceiptNumber, recipte.ReceiptDate.ToString("dd-MM-yyyy"), recipte.ReceiptAmount));
            wndGenerateRecipteNumber.Show();
        }

        /// <summary>
        /// Handles the Clicked event of the btnViewRecipte control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void btnViewRecipte_Clicked(object sender, AjaxEventArgs e)
        {
            if (!LoanID.IsNullOrEmpty())
            {
                ICustomerLoan loan = this.ViewModel.GetLoanById(LoanID.ToGuid());
                ShowRecipteWindow(loan.LoanNumber, loan.CustomerObj.CustomerName, loan.Receipt);
            }
        }

        #endregion

        #endregion

        #region IPermittedPage Members

        /// <summary>
        /// Gets the name of the permission for this page.
        /// </summary>
        /// <value>
        /// The name of the permission.
        /// </value>
        public string PermissionName
        {
            get { return "CreateLoan"; }
        }

        #endregion
    }
}
